home *** CD-ROM | disk | FTP | other *** search
- page 60,132
-
- Title MOVE.COM Ver 1.3 - By Jay B. Harlow - 10 Apr 86
-
- comment /****************************************************************
- * *
- * MOVE.COM *
- * *
- * By Jay B. Harlow *
- * *
- * 10 Apr 86 *
- * *
- * This is a simple program to move files from one directory *
- * to another directory, it works both on one disk and across *
- * more than one disk. Move is easier put works almost *
- * like COPY & DELETE, except when its on the same disk it *
- * simple does a rename function saving on disk space. *
- * Due to DOS, trying to move something to or from a device *
- * simple does not work, so don't try it. *
- * *
- * Ver 1.0 *
- * initial program to rename files from one directory to *
- * to a new directory, works across disks also *
- * *
- * Ver 1.1 added *
- * attempt to correct a bug that would delete files when *
- * renameing to the same name in one directory *
- * intercept Ctrl-C *
- * *
- * Ver 1.2 added *
- * Version fixed a bug that would delete files when *
- * attempting to rename file to the same name *
- * Lets user know if gave too many or too few parameters *
- * Checks diskette space before copying the file across *
- * diskettes *
- * *
- * Ver 1.3 added *
- * moved some variables to the stack to make com file smaller *
- * added Pause option to simplify 2 disk moves *
- * *
- ****************************************************************/
-
- include 186inst.mac ; fake a 80186 instruction set
- include char.def ; define a few character constants
- include dos.mac ; define info on DOS
-
- ; define macros to make working with file size easier
-
- sub32 macro des,src ; subtract 2 32 bit numbers
- mov ax,word ptr src ; low words
- sub word ptr des,ax ; subtract
- mov ax,word ptr src+2 ; high words
- sbb word ptr des+2,ax ; subtract
- endm
-
- add32 macro des,src ; add 2 32 bit numbers
- mov ax,word ptr src ; low words
- add word ptr des,ax ; add
- mov ax,word ptr src+2 ; high words
- adc word ptr des+2,ax ; add
- endm
-
- ; tell the assembler that we are making a COM file
- cseg segment para public 'CODE'
- assume cs:cseg,ss:cseg,ds:cseg,es:cseg
-
- ; Data
-
- ifdef DEBUG ; allow use of symdeb
- public arglen,arg,entry,dta,desdta
- endif ; simplify debugging
-
- org 80h
- arglen db ? ; length of command line
- arg db 7fh dup (?) ; command line from DOS
-
- org 100h
- entry: jmp main ; skip all the data goto main program
-
- db ' MOVE.COM Ver 1.3 - By Jay B. Harlow - 10 Apr 86',eof
-
- dta dta_type <> ; set up a dta for dir search of source
- desdta dta_type <> ; set up a dta for dir search of destination
- ; used to see if source = destination
-
- ifdef DEBUG ; allow use of symdeb
- public size_buffer,num_moved,help
- endif ; simplify debugging
-
- size_buffer dw ? ; number of bytes in copy buffer
- num_moved dw ? ; the number of files moved
-
- help db lf,lf,cr ; a short help message
- db ' MOVE.COM - Move files',lf,cr
- db lf,cr
- db ' Invoke MOVE ? | [option] source filespec[,destination filespec]'
- db lf,cr,lf,cr
- db ' The filespec is [drive][path][filename]',lf,cr
- db ' If only a drive or path is given all the files in',lf,cr
- db ' That drive or path are moved.',lf,cr
- db lf,cr
- db ' Use the P option to pause before moving files',lf,cr
- db lf
- db ' *** WARNING *** Do Not Use on devices!',lf,nul
-
- ifdef DEBUG ; allow use of symdeb
- public notfile,noopenin,noopenout,notransfer,no_param
- public movedmsg1,movedmsg2,movedmsg3,lf_cr,global
- public aborted,incorrect_dos,no_room
- public unknown_option,invalid_option,pause_msg
- endif ; simplify debugging
-
- ; used when a source name wasn't found
- notfile db ' not Found.',nul
-
- ; Couldn't open the input file for copy
- noopenin db 'Unable to open File for Input.',nul
-
- ; Couldn't open the output file for copy
- noopenout db 'Unable to open File for Output.',nul
-
- ; Something went wrong didn't get moved
- notransfer db 'Unable to Move File.',nul
-
- ; didn't find any parameters on command line
- no_param db 'Invalid Number of Parameters.',nul
-
- ; first part of string when printing the number of files moved
- movedmsg1 db ht,nul
-
- ; second part of string when printing the number of files moved
- movedmsg2 db ' File',nul
-
- ; last part of string when printing the number of files moved
- movedmsg3 db ' moved.',nul
-
- ; The transfer was aborted Ctrl-C (Ctrl-break) was hit
- aborted db 'Move Aborted.',nul
-
- ; The program is attempting to use wrong DOS Ver
- incorrect_dos db 'Incorrect DOS Ver.',lf,cr
- db ' This program needs 2.0 or higher.',nul
-
- ; there was not enough room on the destination disk
- no_room db 'Insufficiant room.',nul
-
- ; an incorrect option was given
- invalid_option db ' Invalid Option.',nul
-
- ; an incorrect option was given
- unknown_option db ' Unknown Option.',nul
-
- ; used when want ot pause before moving files
- pause_msg db 'Press Any Key to Continue...',nul
-
- ; end of line - New line
- lf_cr db lf,cr,nul
-
- ; where to go if no specific file is given ( a drive or path only )
- global db '*.*',nul
- len_global = $ - global
-
- ; ROUTINES
-
- jbrk macro des ; jump to des if break was hit
- local cont
- test break,-1
- jz cont
- jmp des
- cont:
- endm
-
- ifdef DEBUG ; allow use of symdeb
- public break,savebreak,_install_break,break_handler,_restore_break
- endif ; simplify debugging
-
- break db 0 ; flag that a Ctrl-C occured
- savebreak dd ? ; someplace save to put old break routine
-
- ; routine to intercept Ctrl-C
- ; installs the break_handler routine to take care of it
-
- install_break macro
- call _install_break
- endm
-
- _install_break proc near
- push es ; save
- mov ax,3523h ; get break vector
- int 21h ; call DOS
- mov word ptr savebreak,bx ; save ip of old break routine
- mov word ptr savebreak+2,es ; save cs of old break routine
- mov ax,2523h ; set new break vector
- lea dx,break_handler ; where the new routine is
- int 21h ; call DOS
- sti ; allow interupts
- pop es ; restore
- ret
- _install_break endp
-
- ; set the break flag to -1 to indicate a Ctrl-C occurred
-
- break_handler proc near
- mov cs:break,-1 ; set the break flag
- iret ; end of interupt
- break_handler endp
-
- restore_break macro
- call _restore_break
- endm
-
- ; routine to restore the Ctrl-C handler back to DOS
-
- _restore_break proc near
- push ds ; save
- mov ax,2523h ; restore break vector
- lds dx,savebreak ; what old vector was
- int 21h ; call DOS
- pop ds ; restore
- ret
- _restore_break endp
-
- ; takes the word ptr off the stack and uses it to print out
- ; an ASCIIZ string
-
- printz macro source
- ifnb <source>
- lea ax,source
- push ax
- endif
- call _printz
- endm
-
- ifdef DEBUG ; allow use of symdeb
- public _printz,printz_loop,printz_exit
- endif ; simplify debugging
-
- _printz proc near ; print a ASCIIZ string (path names)
- enter 0,0
- cld ; ensure left to right
- mov si,word ptr [bp+4] ; get the parameter off stack
- printz_loop:
- lodsb ; get one char
- cmp al,nul ; if not last one
- je printz_exit ; then
- putchar al ; put on screen
- jmp printz_loop ; go for another one
- printz_exit: ; else
- leave ; exit routine
- ret 2 ; discard parameter
- _printz endp
-
- println macro string
- lea ax,string
- push ax
- call _println
- endm
-
- ifdef DEBUG ; allow use of symdeb
- public _println
- endif ; simplify debugging
-
- _println proc near ; print out a string ending w/nul
- string equ word ptr [bp+4]
- enter 0,0
- push string
- printz ; print the string
- printz lf_cr ; goto newline
- leave
- ret 2
- _println endp
-
- ; takes an integer (signed word) off the stack and prints it
- ; non formatted to the screen
-
- printint macro int
- push int
- call _printint
- endm
-
- ifdef DEBUG ; allow use of symdeb
- public _printint,not_negative,int_ascii_loop
- endif ; simplify debugging
-
- _printint proc near
- int equ word ptr [bp+4]
- str equ byte ptr [bp-6]
- enter 6,0
- cld ; left to right
- cmp int,0 ; if int < 0
- jnl not_negative ; then
- putchar '-' ; output a negitive sign
- neg int ; make it positive
- not_negative:
- lea di,str ; scratch buffer
- mov al,0 ; end of str
- mov cx,6 ; max number of characters
- rep stosb ; make str nul
- lea di,str+5 ; where the low digit goes
- mov bx,10
- mov ax,int ; number to print
- int_ascii_loop:
- xor dx,dx ; zero hi word
- div bx ; int / 10
- add dl,'0' ; (int mod 10) + '0'
- dec di ; next char
- mov [di],dl ; save char
- or ax,ax ; see if ax is zero
- jnz int_ascii_loop ; until int is zero
- push di ; pointer to str
- printz ; print out str
- leave
- ret 2 ; discard param
- _printint endp
-
- ; print out the a message telling user number of files moved
- ; the number of files is on the stack
-
- printmoved macro int
- push int
- call _printmoved
- endm
-
- ifdef DEBUG ; allow use of symdeb
- public _printmoved,one
- endif ; simplify debugging
-
- _printmoved proc near
- enter 0,0
- printz movedmsg1 ; print first part of message
- printint int ; print out the integer
- printz movedmsg2 ; middle part of message
- cmp int,1 ; int <> 1
- je one ; then
- putchar 's' ; print an s for syntax
- one:
- println movedmsg3 ; finish the message
- leave
- ret 2 ; discard param
- _printmoved endp
-
- ; routine to check the character in al to see if it is a valid delimeter
-
- ifdef DEBUG ; allow use of symdeb
- public checkdelim,delims
- endif ; simplify debugging
-
- ; the set of valid non delimeters (0-delimeter, 1-nondelimeter)
-
- delims db 00000000B,00000000B,00000000B,00000000B
- db 01011111B,11100111B,11111111B,11100001B
- db 11111111B,11111111B,11111111B,11101011B
- db 11111111B,11111111B,11111111B,11111110B
- db 11111111B,11111111B,11111111B,11111111B
- db 11111111B,11111111B,11111111B,11111111B
- db 11111111B,11111111B,11111111B,11111111B
- db 11111111B,11111111B,11111111B,11111111B
-
- checkdelim proc near ; check al is delimeter
- xor bx,bx ; zero
- mov bl,al ; char to test
- mov cl,al
- mov al,80h
- and cl,7 ; byte location
- shr al,cl ; bit location
- mov cl,3
- shr bx,cl ; byte index
- test delims[bx],al ; is this bit set?
- ret
- checkdelim endp
-
- ; skip all of the delimeters in the param string
-
- skipdelim macro
- call _skip
- endm
-
- ifdef DEBUG ; allow use of symdeb
- public _skip,skiploop,skipexit
- endif ; simplify debugging
-
- _skip proc near ; skip delimeters in command line string
- ; input
- ; AL - has the character
- ; SI - has the string
- ; CX - has the length
- ; output
- ; SI - updated string ptr
- ; CX - updated string length
- jcxz skipexit ; if char then
- skiploop: lodsb ; get a char
- push cx ; save count
- call checkdelim ; while not delimeter
- pop cx ; restore count
- loope skiploop ; where found
- je skipexit ; nothing found
- dec si ; point to character found
- inc cx ; count of string
- skipexit:
- ret
- _skip endp
-
- ; save the parameter w/conversion to uppercase
-
- savenam macro where
- lea di,where
- call _save
- endm
-
- ifdef DEBUG ; allow use of symdeb
- public _save,save_loop,save_char,not_lower,save_exit
- endif ; simplify debugging
-
- _save proc near ; routine to move token
- ; input
- ; SI - has the string
- ; DI - has the destination
- ; CX - has the length of the string
- ; output
- ; SI - updated delimeter left in string
- ; CX - updated
- jcxz save_exit ; if nothing there
- save_loop: lodsb ; get a char
- push ax ; save character
- push cx ; save count
- call checkdelim ; while not delimeter
- pop cx ; restore count
- pop ax ; restore character
- jne save_char ; if delimeter
- dec si ; point to last char
- jmp short save_exit ; else
- save_char:
- cmp al,'a' ; is it lower case
- jb not_lower
- cmp al,'z'
- ja not_lower
- and al,5fh ; make upper case
- not_lower:
- stosb ; save the char
- loop save_loop ; not end of line
- save_exit: ; exit
- mov byte ptr [di],0 ; end of string
- ret
- _save endp
-
- checkparam macro param
- lea di,param
- call _checkparam
- endm
-
- ifdef DEBUG ; allow use of symdeb
- public _checkparam,checkparam_exit,option,option_bad
- endif ; simplify debugging
-
- _checkparam proc near
- push cx
- push si
- cmp byte ptr [di],'/' ; option can have either forward slash
- je option
- cmp byte ptr [di],'-' ; or a minus sign as the legal indicator
- je option
- clc ; flag no option present
- checkparam_exit:
- pop si
- pop cx
- ret
- option: cmp byte ptr [di+2],nul ; check option one character only
- jne option_bad
- cmp byte ptr [di+1],'P' ; is it a P
- jne not_p
- println pause_msg ; ask user to press a key
- mov ax,0c07h ; wait until keypressed
- int 21h
- cmp al,3 ; was Ctrl-C pressed
- stc ; signal an option
- jne checkparam_exit
- mov break,-1 ; set the break flag
- stc ; signal an option
- jmp checkparam_exit
- not_p:
- push di ; print out the option given
- printz
- println unknown_option ; tell user its bad
- stc ; signal an option
- jmp checkparam_exit
- option_bad:
- push di ; print out the option given
- printz
- println invalid_option ; tell user its bad
- stc ; signal an option
- jmp checkparam_exit
- _checkparam endp
-
- ; routine to search a string for a specific character
-
- searchchar macro string,char
- mov di,string
- mov al,char
- call _searchchar
- endm
-
- ifdef DEBUG ; allow use of symdeb
- public _searchchar,search_next,search_more,search_exit
- endif ; simplify debugging
-
- _searchchar proc near ; see if char in al is in string @ di
- enter 0,0
- push di ; save index for later
- cld ; follow string left to right
- search_next:
- scasb ; is this one
- jne search_more ; than
- stc ; -1
- sbb di,[bp-2] ; index into string where found
- mov ax,di ; return index
- jmp short search_exit ; else
- search_more:
- cmp byte ptr [di-1],0 ; end of string ?
- jne search_next
- mov ax,-1 ; not the character return -1
- search_exit:
- leave
- ret
- _searchchar endp
-
- ; routine to check the filespec to insure it is valid
- ; it also adds a *.* on the end if it is a path (drive)
- ; if a \ is needed first it is also added
-
- checkpath macro path
- lea ax,path
- push ax
- call _checkpath
- endm
-
- ifdef DEBUG ; allow use of symdeb
- public _checkpath,put_global,checkpath_exit
- endif ; simplify debugging
-
- path equ word ptr [bp+4]
- pathend equ word ptr [bp-2]
- _checkpath proc near ; routine to see if input is a dir
- enter 2,0 ; if it is a \ is tacked on end if needed
- cld ; left to right
- mov di,path ; point at the path
- cmp byte ptr [di],0 ; is the path empty
- je put_global ; yes put on star-dot-star
- searchchar path,0 ; look for end of string
- add ax,path ; point to the end of the path
- mov pathend,ax ; save the pointer to the end of the path
- mov di,ax ; use a pointer register!
- cmp byte ptr [di-1],':' ; is this just a drive spec?
- je put_global ; then put on global search info
- cmp byte ptr [di-1],'\' ; is there a slash there already?
- je put_global ; then put on global search info
- searchchar path,'*' ; check to see if wildcard
- cmp ax,-1 ; found?
- jne checkpath_exit ; exit routine
- searchchar path,'?' ; check to see if wildchar
- cmp ax,-1 ; found?
- jne checkpath_exit ; exit routine
- mov dta.dta_attr,not is_dir ; set attribute to known value
- mov dx,path ; what to look for
- mov cx,is_dir ; look only for a directory
- mov ah,4eh ; search for entry
- int 21h
- cmp dta.dta_attr,cl ; is it the same attribute
- jne checkpath_exit ; if found
- mov di,pathend ; point to end of path
- mov al,'\'
- stosb ; tack on a slash
- put_global:
- lea si,global ; what to append ( di has where to put )
- mov cx,len_global ; how much to append
- rep movsb ; tack on global to end of path
- checkpath_exit:
- leave
- ret 2
- _checkpath endp
-
- ; routine to copy just the path off of a string and put it in the
- ; destination, returning the length of the path saved
-
- savepath macro inpath,outpath
- ifnb <inpath>
- lea ax,inpath
- push ax
- endif
- ifnb <outpath>
- lea ax,outpath
- push ax
- endif
- call _savepath
- endm
-
- inpath equ word ptr [bp+6]
- outpath equ word ptr [bp+4]
-
- ifdef DEBUG ; allow use of symdeb
- public _savepath,back_not_found,save
- endif ; simplify debugging
-
- _savepath proc near ; move just the path to destination
- enter 0,0
- searchchar inpath,0 ; look for end of inpath
- mov bx,ax ; save length
- mov di,inpath ; point to the path
- lea di,[di+bx] ; save pointer to last char
- mov cx,bx ; number of bytes to look at
- inc cx ; inc length of the path for # chars
- std ; right to left
- mov al,'\' ; dir char
- repne scasb ; look for
- jne back_not_found ; if found
- inc cx ; inc length of the path
- jmp short save ; else
- back_not_found:
- mov di,inpath ; point to the path
- lea di,[di+bx] ; save pointer to last char
- mov cx,bx ; number of bytes to look at
- inc cx ; inc length of the path for # chars
- mov al,':' ; drive char
- repne scasb ; look for char
- jne save ; if found
- inc cx ; inc length of the path
- save: mov si,inpath ; where get
- mov di,outpath ; where put
- mov ax,cx ; save len of path for return
- cld ; left to right
- rep movsb ; save the path
- leave
- ret 4
- _savepath endp
-
- incchar macro regptr ; macro to move ptr in filename
- local _inc_skip
- cmp byte ptr [regptr],'.'
- je _inc_skip
- cmp byte ptr [regptr],0
- je _inc_skip
- inc regptr
- _inc_skip:
- endm
-
- movchar macro regptr ; macro to move char in filename
- local mov_exit
- cmp byte ptr [regptr],0
- je mov_exit
- cmp byte ptr [regptr],'.'
- je mov_exit
- mov al,[regptr]
- stosb
- inc regptr
- mov_exit:
- endm
-
- movall macro regptr ; macro to move all of filename
- local mov_loop,mov_exit
- mov_loop:
- cmp byte ptr [regptr],0
- je mov_exit
- cmp byte ptr [regptr],'.'
- je mov_exit
- mov al,[regptr]
- stosb
- inc regptr
- jmp mov_loop
- mov_exit:
- endm
-
- extention macro regptr ; move to char after '.'
- local ext_loop,ext_exit
- ext_loop:
- cmp byte ptr [regptr],0
- je ext_exit
- cmp byte ptr [regptr-1],'.'
- je ext_exit
- inc regptr
- jmp short ext_loop
- ext_exit:
- endm
-
- ; this routine takes the oldname and searches the source
- ; creating the newname, expanding or dropping characters
- ; to come up the the destination name
-
- makename macro oldname,source,newname
- lea ax,oldname
- push ax
- lea ax,source
- push ax
- lea ax,newname
- push ax
- call _makename
- endm
-
- oldname equ word ptr [bp+8]
- source equ word ptr [bp+6]
- newname equ word ptr [bp+4]
-
- ifdef DEBUG ; allow use of symdeb
- public _makename,make_loop,not_wildchar
- public not_wildcard,not_period,make_exit
- endif ; simplify debugging
-
- _makename proc near ; routine to make a destination name
- enter 0,0
- push source ; address of inpath
- push newname ; address of outpath
- savepath ; parameters on stack (indirection)
- mov bx,ax
- mov si,source
- mov di,newname
- lea si,[si+bx] ; point to the filename itself
- lea di,[di+bx] ; point to where the new name is put
- mov bx,oldname ; point to filename found
- make_loop:
- lodsb ; get one char in source
- cmp al,'?'
- jne not_wildchar ; if question mark
- movchar bx ; copy one char from oldname
- jmp make_loop
- not_wildchar:
- cmp al,'*'
- jne not_wildcard ; if asterick
- movall bx ; copy rest of oldname
- extention si ; goto extention in source
- cmp byte ptr [si-1],'.' ; see if a period is needed
- jne make_loop
- dec si ; restore period if needed
- jmp make_loop
- not_wildcard:
- stosb ; save this char in the string
- cmp al,'.'
- jne not_period ; if period
- extention bx ; goto extention in oldname
- jmp make_loop
- not_period:
- cmp al,0
- je make_exit
- incchar bx ; move one in oldname
- jmp make_loop
- make_exit:
- leave
- ret 6
- _makename endp
-
- ; routine to return the id of the drive the filespec is on
- ; 0-A, 1-B, 2-C.... -1 invalid drive (device?)
-
- drive macro path,id
- mov si,path
- mov al,id
- call _drive
- endm
-
- ifdef DEBUG ; allow use of symdeb
- public _drive,drive_error,no_drive,drive_exit
- endif ; simplify debugging
-
- _drive proc near
- cmp al,1 ; length to ':' as parameter
- jg drive_error
- jl no_drive
- lodsb ; get the drive letter
- cmp al,'A' ; is it a valid char
- jb drive_error
- cmp al,'Z' ; its upper case
- ja drive_error
- sub al,'A' ; change into code
- jmp short drive_exit
- no_drive:
- mov ah,19h ; get current drive id
- int 21h ; find id
- jmp short drive_exit
- drive_error:
- mov al,-1
- drive_exit:
- ret
- _drive endp
-
- get_disk_left macro source
- ifnb <source>
- lea ax,source
- push ax
- endif
- call _get_disk_left
- endm
-
- ifdef DEBUG ; allow use of symdeb
- public _get_disk_left
- endif ; simplify debugging
-
- _get_disk_left proc near ; function to find bytes left on disk
- enter 0,0
- searchchar path,':' ; look to see if this is a drivespec
- drive path,al ; return the drive code if it is filespec
- mov dl,al ; find amount of space left on disk
- inc dl ; actuall drive for free space
- mov ah,36h ; get disk params
- int 21h ; call DOS
- mul bx ; sectors/cluster x # free clusters
- mul cx ; dx:ax = # bytes left on disk
- leave
- ret 2
- _get_disk_left endp
-
- ; routine to look at the two file specs and determine whether
- ; we need to simple rename the files or to copy the files
-
- findroutine macro filespec1,filespec2
- lea ax,filespec1
- push ax
- lea ax,filespec2
- push ax
- call _findroutine
- endm
-
- infile equ word ptr [bp+6] ; pointer to filespec of input file
- outfile equ word ptr [bp+4] ; pointer to filespec of output file
-
- drive1 equ byte ptr [bp-1] ; place to save id
- drive2 equ byte ptr [bp-2] ; " " " "
-
- ifdef DEBUG ; allow use of symdeb
- public _findroutine,use_rename,drive_length
- public check_defaults,use_copy,find_exit
- endif ; simplify debugging
-
- _findroutine proc near ; routine to check for rename or copy
- enter 2,0
- searchchar infile,':' ; look for drive specification
- mov drive1,al ; save index
- searchchar outfile,':' ; look for drive specification
- mov drive2,al ; save index
- cmp al,drive1 ; have same length
- jne check_defaults
- cmp al,-1 ; if no length
- jne drive_length
- use_rename: lea ax,_rename ; all on the same drive
- jmp short find_exit
- drive_length: ; see if drive specifies are same?
- mov cx,ax ; number to compare
- mov si,infile ; first path
- mov di,outfile ; second path
- repe cmpsb ; compare these two drive specs
- je use_rename ; if equal goto rename
- jmp short use_copy ; else goto copy
- check_defaults: ; see if refer to same
- drive infile,drive1 ; find drive id for in filespec
- mov drive1,al
- cmp al,-1
- je use_copy
- drive outfile,drive2 ; " " " " out filespec
- cmp al,-1
- je use_copy ; one may be a device
- cmp al,drive1
- je use_rename ; drives are the same
- use_copy:
- lea ax,_copy
- find_exit:
- leave
- ret 4
- _findroutine endp
-
- srchdir macro dta,src,attr
- setdta dta ; use this dta
- mov dx,src ; filename to look for
- ifnb <attr>
- mov cx,attr ; use this attribute
- else
- xor cx,cx ; use zero
- endif
- mov ah,4eh ; do a DIR search
- int 21h ; call DOS
- endm
-
- ; routine to copy the infile to the outfile
-
- inhandle equ word ptr [bp-2] ; handle to input filespec
- outhandle equ word ptr [bp-4] ; handle to output filespec
-
- ifdef DEBUG ; allow use of symdeb
- public _copy,is_room,no_add,opened_infile
- public opened_outfile,copy_aborted,copy_block
- public copy_notokay,copy_okay,copy_exit,copy_error
- endif ; simplify debugging
-
- _copy proc near ; routine to copy files between disks
- disk_left equ word ptr [bp-8] ; 32-bit value of bytes left on disk
- enter 8,0 ; set stack w/ 2 words storage
- mov outhandle,-1 ; flag that no file was open
- jbrk copy_exit
- push outfile ; the parameter to get_disk_left
- get_disk_left ; set the amount of space on disk
- mov word ptr disk_left,ax
- mov word ptr disk_left+2,dx ; set the amount of space left
- srchdir desdta,outfile ; look for srcwild using the outfile
- jc no_add ; no error then
- add32 disk_left,desdta.dta_size
- no_add:
- sub32 disk_left,dta.dta_size ; enough room on disk
- jnb is_room
- println no_room ; tell user no room
- mov break,1
- jmp copy_exit
- is_room:
- mov dx,infile ; point to input filespec
- mov ax,3d00h ; open for read
- int 21h ; call DOS
- jnc opened_infile
- println noopenin ; print a message
- mov break,1 ; return to DOS w/ error code
- jmp copy_exit
- opened_infile:
- mov inhandle,ax ; save the input handle
- lea dx,buffer
- copy_block:
- jbrk copy_aborted ; if flag set abort
- mov cx,size_buffer ; length of buffer
- mov bx,inhandle ; the input filespec
- mov ah,3fh ; read from input file
- int 21h ; call DOS
- mov cx,ax ; amount read
- cmp outhandle,-1 ; if out file not opened
- jne opened_outfile ; then
- push cx ; save the length
- mov dx,outfile ; point to output filespec
- xor cx,cx ; no attribute
- mov ax,3c01h ; open for write
- int 21h ; call DOS
- mov outhandle,ax ; save the output handle
- lea dx,buffer ; address of buffer
- pop cx ; restore the length to write
- jnc opened_outfile
- println noopenout ; print a message
- mov break,1 ; signal an error
- jmp short copy_exit
- opened_outfile:
- jbrk copy_aborted ; if flag set abort
- mov bx,outhandle ; the output filespec
- mov ah,40h ; write to output file
- int 21h ; call DOS
- jc copy_notokay
- cmp ax,cx ; write all we wanted?
- je copy_okay ; no than
- copy_notokay: ; for some reason didn't work
- println notransfer
- mov break,1 ; signal an error
- jmp short copy_error
- copy_okay:
- cmp ax,size_buffer ; until end of file
- je copy_block
- mov dx,dta.dta_date ; get found files date
- mov cx,dta.dta_time ; get found files time
- mov bx,outhandle
- mov ax,5701h ; set date:time of output file
- int 21h
- close outhandle ; close output file
- close inhandle ; close input file
- mov bx,infile ; get address of infile
- delete [bx] ; delete input file bx points to it
- inc num_moved ; one filed moved
- jmp short copy_exit
- copy_aborted:
- println aborted ; tell user about error
- copy_error:
- close inhandle ; close input file
- close outhandle ; close output file
- copy_exit:
- leave ; reset stack
- ret 4 ; discard parameters and exit
- _copy endp
-
- ; routine to rename the input filespec to the output filespec
-
- ifdef DEBUG ; allow use of symdeb
- public _rename,try_rename,rename_nogo,rename_good,rename_exit
- endif ; simplify debugging
-
- _rename proc near ; routine to rename the files
- enter 0,0 ; set stack
- test break,-1 ; see if an error occured somewhere
- jz try_rename
- println aborted
- jmp short rename_exit
- try_rename:
- mov dx,infile ; point to current name
- mov di,outfile ; point to new name
- mov ah,56h ; rename function
- int 21h ; call DOS
- jnc rename_good ; simply renameing didn't work
- srchdir desdta,outfile ; look for srcwild using the outfile
- jc rename_nogo ; no error then
- lea si,dta.dta_reserved ; address of the source dta
- lea di,desdta.dta_reserved ; address of the destination dta
- mov cx,size dta - dta_reserved ; number of bytes in dta
- rep cmpsb ; compare the two dta ( same filespecs?)
- je rename_nogo ; same then
- mov dx,outfile ; point to destination filespec
- mov ah,41h ; function to delete a entry
- int 21h ; call DOS
- jnc try_rename ; still didn't work
- rename_nogo:
- println notransfer ; tell user about this problem
- mov break,1 ; signal a error occured
- jmp short rename_exit
- rename_good:
- inc num_moved ; one file moved
- rename_exit:
- leave
- ret 4
- _rename endp
-
- ; macro to call the proper move procedure
-
- move macro src,des,proc
- lea ax,src
- push ax
- lea ax,des
- push ax
- call proc
- endm
-
- ; routine to look for all the files with the srcwild filespec
- ; and move them to files with the deswild filespec
-
- moveall macro routineptr
- push routineptr
- call _moveall
- endm
-
- ifdef DEBUG ; allow use of symdeb
- public _moveall,first_entry,next_entry,mov_loop,moveall_exit
- endif ; simplify debugging
-
- _moveall proc near ; looks for and moves all files
- srcwild equ byte ptr [bp+86] ; the source filespec w/global
- deswild equ byte ptr [bp+6] ; the destination filespec w/global
- mvproc equ word ptr [bp+4] ; routine to use in transfer
- srclen equ word ptr [bp-2] ; length of the finame found
- src equ byte ptr [bp-82] ; the source filespec
- des equ byte ptr [bp-162] ; the destination filespec
- enter 162,0 ; locals = src,des,srclen
- mov num_moved,0 ; no files moved
- savepath srcwild,src ; move the path into name
- mov srclen,ax ; length of the path
- first_entry:
- setdta dta ; use this dta
- lea dx,srcwild ; filename to look for
- xor cx,cx ; use zero
- mov ah,4eh ; do a DIR search
- int 21h ; call DOS
- jnc next_entry ; if not found
- printz srcwild ; print out the name looking for
- println notfile ; print a error message
- mov break,1 ; exit w/error
- jmp moveall_exit
- next_entry:
- mov di,srclen ; length of path
- lea di,src[di] ; point to end of path
- lea si,dta.dta_name ; point to filename found
- mov_loop:
- lodsb ; move file name found
- stosb ; to end of path
- cmp al,0 ; until a zero was moved
- jne mov_loop
- println src ; print out the filespec that is being moved
- makename dta.dta_name,deswild,des
- move src,des,mvproc ; move this file found
- jbrk moveall_exit
- setdta dta ; tell dos where file info is
- mov ah,4fh ; find next
- int 21h
- jnc next_entry ; repeat until no more
- moveall_exit:
- printmoved num_moved ; print out the number of files moved
- leave
- ret 2
- _moveall endp
-
- ; this is the main program it
- ; takes over Ctrl-C
- ; checks for parameters and if help is wanted
- ; sets up the size of the copy buffer if it is needed
- ; parses the command line for the source and destination filespecs
- ; decides which routine to use
- ; calls the procedure to move all of the files.
- ; restores Ctrl-C
- ; returns to DOS with
- ; 0 : noerror
- ; 1 : DOS error
- ; -1 : Ctrl-C was pressed
-
- ifdef DEBUG ; allow use of symdeb
- public main,dos_good,check_help,maincont,mainexit,invalid_param
- public getparam1,getparam2
- endif ; simplify debugging
-
- main proc near ; main procedure in program
- param1 equ byte ptr [bp-80] ; the current source filespec
- param2 equ byte ptr [bp-160] ; the current destination filespec
- enter 160,0
- mov ah,30h ; get version number
- int 21h
- cmp ax,2 ; correct version
- jnb dos_good
- println incorrect_dos ; tell user dos is no good
- exit 1 ; return w/ error
- dos_good:
- cld ; left to right on strings
- lea si,arg ; get ptr to command line
- xor ch,ch ; high part of length
- mov cl,arglen ; cx <- length of command line
- skipdelim ; skip all delimeters
- cmp cx,0 ; are there any parameters
- jne check_help ; if not than
- invalid_param: ; tell user of error
- println no_param ; error message
- exit 1 ; exit with error code
- check_help: ; else parameters
- cmp byte ptr [si],'?' ; any help
- jne maincont ; then
- cmp cx,1 ; if only one character in buffer
- jne maincont ; then
- println help ; help message
- exit 0 ; return to DOS
- maincont:
- install_break ; handle break key myself
- setdta dta ; set up the dta for checkpath
- mov ax,sp ; number of bytes in segment
- sub ax,1000h ; set aside room for stack
- sub ax,offset buffer ; leave the code alone
- mov size_buffer,ax ; save the length of the buffer
- getparam1: cmp cx,0
- je invalid_param ; if no more parameters
- savenam param1 ; save the source filespec
- skipdelim ; skip all delimeters
- checkparam param1 ; see if option
- jc getparam1
- getparam2: savenam param2 ; save the destination filespec
- skipdelim ; skip all delimeters
- checkparam param2 ; see if option
- jc getparam2
- cmp cx,0 ; if another param
- jnz invalid_param ; then tell user
- checkpath param1 ; fix the source if its a path
- checkpath param2 ; fix the destination if its a path
- findroutine param1,param2 ; look for the routine to use
- jbrk mainexit
- moveall ax ; ax has pointer to function
- mainexit:
- restore_break
- leave
- exit break ; terminate process
- main endp
-
- ifdef DEBUG ; allow use of symdeb
- public buffer
- endif ; simplify debugging
-
- buffer label byte ; this is where the buffer is
-
- cseg ends
- end entry
-